home *** CD-ROM | disk | FTP | other *** search
- {
-
- SampleXsn.c
-
- Sample transition effect for VideoShop
-
- 04/28/92 Ivçn Cavero Bela£nde
-
- }
-
- UNIT SampleTransition;
-
- INTERFACE
-
- USES
- Types,Memory,Resources,QuickDraw,QDOffscreen,Dialogs,OSUtils,Packages,Errors,
- ToolUtils,SysEqu,GestaltEqu,DiVATransition;
-
- FUNCTION XsnEntryPoint(selector: INTEGER; params: XsitionParamPtr; VAR data: LONGINT;
- transitionIntensity, maxTransitionIntensity: INTEGER): XsnErr;
-
- FUNCTION DoParameters(params: XsitionParamPtr): XsnErr;
-
- FUNCTION DoProcessFrame(params: XsitionParamPtr; transitionIntensity,
- maxTransitionIntensity: INTEGER): XsnErr;
-
- IMPLEMENTATION
-
- CONST
-
- { Dialog item constants }
-
- dialogID = 16001;
- defaultItem = 3;
- leftToRightItem = 5;
- topToBottomItem = 6;
- rightToLeftItem = 7;
- bottomToTopItem = 8;
- dividerItem = 10;
-
- TYPE
-
- WipeParams = RECORD
- angle: INTEGER;
- END;
-
- WipeParamPtr = ^WipeParams;
- WipeParamHandle = ^WipeParamPtr;
-
- RGBColorPtr = ^RGBColor;
-
- FUNCTION XsnEntryPoint(selector: INTEGER; params: XsitionParamPtr; VAR data: LONGINT;
- transitionIntensity, maxTransitionIntensity: INTEGER): XsnErr;
- {
- The transition entry point and dispatcher routine. Calls the appropriate
- subroutine based on the selector passed.
- }
- BEGIN
- CASE selector OF
- XSParameters:
- XsnEntryPoint := DoParameters (params);
- XSPrepare:
- XsnEntryPoint := noErr;
- XSStart:
- XsnEntryPoint := noErr;
- XSProcessFrame:
- XsnEntryPoint := DoProcessFrame(params,transitionIntensity,maxTransitionIntensity);
- XSFinish:
- XsnEntryPoint := noErr;
- OTHERWISE
- XsnEntryPoint := -1;
- END;
- END;
-
-
- FUNCTION DoTestAbort(codeAddress: ProcPtr): BOOLEAN;
- { Inline code to call the TestAbort function }
- INLINE $205F, { move.l (a7)+,a0 pop procPtr from stack }
- $4E90; { jsr (a0) and call it }
-
- FUNCTION TestAbort (params: XsitionParamPtr): BOOLEAN;
- BEGIN
- TestAbort := DoTestAbort(params^.abortProc);
- END;
-
- PROCEDURE DoUpdateProgress(done, total: LONGINT; codeAddress: ProcPtr);
- { Inline code to call the UpdateProgress function }
- INLINE $205F, { move.l (a7)+,a0 pop procPtr from stack }
- $4E90; { jsr (a0) and call it }
-
- PROCEDURE UpdateProgress(params: XsitionParamPtr; done, total: LONGINT);
- BEGIN
- DoUpdateProgress(done,total,params^.progressProc);
- END;
-
- PROCEDURE CenterDialog(dt: DialogTHndl);
- {
- Given a dialog template in dt, modify it so as to center the dialog on the
- main device.
- }
- VAR
- width, height: INTEGER;
- mainDevice: GDHandle;
- r,dr: Rect;
- BEGIN
- mainDevice := GetMainDevice;
- r := mainDevice^^.gdRect;
- width := r.right - r.left;
- height := r.bottom - r.top;
-
- dr := dt^^.boundsRect;
- OffsetRect (dr, r.left-dr.left, r.top-dr.top);
- OffsetRect (dr, (width - (dr.right-dr.left)) DIV 2,
- (height - (dr.bottom-dr.top) - GetMBarHeight) DIV 3 + GetMBarHeight);
- dt^^.boundsRect := dr;
- END;
-
- PROCEDURE OutlineOK(dp: DialogPtr; item: INTEGER);
- {
- userItem drawing routine for outlining the default button in the dialog box
- }
- VAR
- r: Rect;
- h: Handle;
- itemType: INTEGER;
- BEGIN
- item := ok;
- GetDItem (dp, item, itemType, h, r);
- PenNormal;
- PenSize (3, 3);
- InsetRect (r, -4, -4);
- FrameRoundRect (r, 16, 16);
- PenNormal;
- END;
-
- FUNCTION GetWindowGDevice(w: WindowPtr): GDHandle;
- {
- Find the deepest gdevice the window intersects. Used for determining the depth
- of the screen we're drawing on (to look good on B/W displays).
- }
- VAR
- r: Rect;
- oldPort: GrafPtr;
- BEGIN
- GetPort(oldPort);
- SetPort(w);
- r := w^.portRect;
- LocalToGlobal(r.topLeft);
- LocalToGlobal(r.botRight);
- GetWindowGDevice := GetMaxDevice(r);
- SetPort (oldPort);
- END;
-
- PROCEDURE DrawLines(theDialog: DialogPtr; itemNo: INTEGER);
- {
- userItem drawing routine for dividing lines (with shadow)
- }
- VAR
- oldColor, greyColor: RGBColor;
- itemType: INTEGER;
- me: Handle;
- box: Rect;
- BEGIN
- GetDItem(theDialog,itemNo,itemType,me,box);
- GetForeColor(oldColor);
- RGBForeColor(RGBColorPtr(RGBBlack)^);
- MoveTo(box.left,box.top);
- LineTo(box.right-2,box.top);
- MoveTo(box.left,box.top+3);
- LineTo(box.right-2,box.top+3);
- IF (GetWindowGDevice(theDialog)^^.gdPMap^^.pixelSize >= 8) THEN
- BEGIN
- greyColor.red := $7777;
- greyColor.green := $7777;
- greyColor.blue := $7777;
- RGBForeColor (greyColor);
- MoveTo(box.left+1, box.top+1);
- LineTo(box.right-1, box.top+1);
- MoveTo(box.left+1, box.top+4);
- LineTo(box.right-1, box.top+4);
- END;
- RGBForeColor(oldColor);
- END;
-
- PROCEDURE SetupDItems (dp: DialogPtr);
- VAR
- itemType: INTEGER;
- h: Handle;
- r: Rect;
- BEGIN
- { Point default useritem to default button outline routine }
- GetDItem (dp, defaultItem, itemType, h , r);
- SetDItem (dp, defaultItem, itemType, Handle(@OutlineOK), r);
-
- { Point divider lines useritem to dividing lines drawing routine }
- GetDItem (dp, dividerItem, itemType, h , r);
- SetDItem (dp, dividerItem, itemType, Handle(@DrawLines), r);
- END;
-
- PROCEDURE TurnAllOffButMe(dp: DialogPtr; itemNo: INTEGER);
- {
- Turn off all but one control dialog items in a given range. Used for managing
- sets of radio buttons.
- }
- VAR
- j,itemType : INTEGER;
- h: Handle;
- r: Rect;
- BEGIN
- FOR j:=leftToRightItem TO bottomToTopItem DO
- IF (j <> itemNo) THEN BEGIN
- GetDItem (dp,j,itemType,h,r);
- SetCtlValue(ControlHandle(h),0);
- END;
- GetDItem (dp,itemNo,itemType,h,r);
- SetCtlValue(ControlHandle(h),1);
- END;
-
- PROCEDURE RecalcDItems (p: WipeParamHandle; dp: DialogPtr);
- BEGIN
- CASE p^^.angle OF
- 0:
- TurnAllOffButMe(dp,bottomToTopItem);
- 90:
- TurnAllOffButMe(dp,leftToRightItem);
- 180:
- TurnAllOffButMe(dp,topToBottomItem);
- 270:
- TurnAllOffButMe(dp,rightToLeftItem);
- OTHERWISE
- BEGIN
- TurnAllOffButMe(dp,leftToRightItem);
- p^^.angle := 90;
- END;
- END;
- END;
-
- FUNCTION DoParameters (params: XsitionParamPtr): XsnErr;
- {
- Prompt the user for parameters if necessary.
- }
- VAR
- item: INTEGER;
- dp: DialogPtr;
- dt: DialogTHndl;
- theParams: WipeParamHandle;
-
- BEGIN
- { If we didn't get passed a params handle, allocate and initialize it }
- IF (params^.parameters = NIL) THEN BEGIN
- theParams := WipeParamHandle(NewHandleClear(sizeof(WipeParams)));
- IF (theParams = NIL) THEN BEGIN
- DoParameters := XSErrOutOfMemory + MemError;
- Exit(DoParameters);
- END;
- theParams^^.angle := 90;
- END
- ELSE BEGIN
- {
- Otherwise, we just return. If we required specific hardware or mounds of
- memory we would check here.
- }
- DoParameters := noErr;
- Exit(DoParameters);
- END;
-
- { Load in the dialog and reposition it in the best device }
- dt := DialogTHndl(GetResource ('DLOG', dialogID));
- HNoPurge (Handle(dt));
- CenterDialog (dt);
-
- { Show it }
- dp := GetNewDialog (dialogID, nil, WindowPtr(-1));
-
- { Setup the user items and initialize all controls to initial state }
- SetupDItems(dp);
- RecalcDItems(theParams,dp);
-
- REPEAT
- ModalDialog (nil, item);
- CASE item OF
- topToBottomItem:
- BEGIN
- theParams^^.angle := 180;
- RecalcDItems (theParams, dp);
- END;
- leftToRightItem:
- BEGIN
- theParams^^.angle := 90;
- RecalcDItems (theParams, dp);
- END;
- bottomToTopItem:
- BEGIN
- theParams^^.angle := 0;
- RecalcDItems (theParams, dp);
- END;
- rightToLeftItem:
- BEGIN
- theParams^^.angle := 270;
- RecalcDItems (theParams, dp);
- END;
- END;
- UNTIL ((item = ok) OR (item = cancel));
-
- DisposDialog (dp);
- HPurge (Handle(dt));
-
- IF (item = cancel) THEN BEGIN
- DisposHandle(Handle(theParams));
- params^.parameters := nil;
- DoParameters := XSErrReported;
- Exit (DoParameters);
- END;
- params^.parameters := Handle(theParams);
- DoParameters := noErr;
- END;
-
- FUNCTION DoProcessFrame(params: XsitionParamPtr; transitionIntensity,
- maxTransitionIntensity: INTEGER): XsnErr;
- { Perform the effect }
- VAR
- pmStateA,pmStateB,pmStateDest: GWorldFlags;
- oldGW,destGW: GWorldPtr;
- oldGD: GDHandle;
- srcA,srcB,dest: PixMapHandle;
- stateA,stateB,stateDest: SignedByte;
- r,bounds: Rect;
- xSize, ySize, angle: INTEGER;
- oldFore, oldBack: RGBColor;
- p: WipeParamHandle;
- dummy: BOOLEAN;
- BEGIN
- p := WipeParamHandle(params^.parameters);
-
- IF (TestAbort (params)) THEN BEGIN
- DoProcessFrame := XSErrReported;
- Exit (DoProcessFrame);
- END;
-
- srcA := params^.srcA;
- srcB := params^.srcB;
- destGW := params^.destImage;
-
- { Get the image pixmaps, dealing with pre-System 7 GetGWorldPixMap bug }
- IF (IntegerPtr(SysVersion)^ < $700) THEN
- dest := destGW^.portPixMap
- ELSE
- dest := GetGWorldPixMap (destGW);
-
- r := srcA^^.bounds;
- bounds := r;
- ySize := r.bottom - r.top;
- xSize := r.right - r.left;
-
- { Spin the beachball }
- UpdateProgress (params,0,3);
-
- { Calculate the rectangle to copy based on the wipe direction }
- angle := p^^.angle;
- CASE angle OF
- 0:
- BEGIN
- SetRect (r,0,0,xSize,ySize);
- r.top := r.bottom - (transitionIntensity * xSize DIV maxTransitionIntensity);
- END;
- 90:
- BEGIN
- SetRect (r,0,0,xSize,ySize);
- r.right := r.left + (transitionIntensity * xSize DIV maxTransitionIntensity);
- END;
- 180:
- BEGIN
- SetRect (r,0,0,xSize,ySize);
- r.bottom := r.top + (transitionIntensity * ySize DIV maxTransitionIntensity);
- END;
- 270:
- BEGIN
- SetRect (r,0,0,xSize,ySize);
- r.left := r.right - (transitionIntensity * xSize DIV maxTransitionIntensity);
- END;
- OTHERWISE
- BEGIN
- SetRect (r,0,0,xSize,ySize);
- r.top := r.bottom - (transitionIntensity * xSize DIV maxTransitionIntensity);
- END;
- END;
-
- { spin the beachball }
- UpdateProgress (params,1,3);
-
- { save offscreen pixels state and lock them down for drawing }
- pmStateA := GetPixelsState(srcA);
- dummy := LockPixels (srcA);
- stateA := HGetState (Handle(srcA));
- MoveHHi (Handle(srcA));
- HLock (Handle(srcA));
-
- pmStateB := GetPixelsState(srcB);
- dummy := LockPixels (srcB);
- stateB := HGetState (Handle(srcB));
- MoveHHi (Handle(srcB));
- HLock (Handle(srcB));
-
- pmStateDest := GetPixelsState(dest);
- dummy := LockPixels (dest);
- stateDest := HGetState (Handle(dest));
- MoveHHi (Handle(dest));
- HLock (Handle(dest));
-
- { save drawing state }
- GetGWorld (oldGW,oldGD);
- SetGWorld (destGW,GetGWorldDevice(destGW));
- GetForeColor (oldFore);
- GetBackColor (oldBack);
- RGBForeColor (RGBColorPtr(RGBBlack)^);
- RGBBackColor (RGBColorPtr(RGBWhite)^);
-
- { copy entire first source image }
- CopyBits(BitMapHandle(srcA)^^,BitMapHandle(dest)^^,bounds,bounds,srcCopy,nil);
-
- { spin beachball, restoring original graphic state }
- SetGWorld (oldGW,oldGD);
- UpdateProgress (params,2,3);
- SetGWorld (destGW,GetGWorldDevice(destGW));
-
- { wait for accelerators }
- WHILE (NOT (QDDone(GrafPtr(destGW)))) DO;
-
- { copy the piece of the second source that we calculated earlier }
- CopyBits(BitMapHandle(srcB)^^,BitMapHandle(dest)^^,r,r,srcCopy,nil);
-
- { wait for accelerators }
- WHILE (NOT (QDDone(GrafPtr(destGW)))) DO;
-
- { restore graphic state }
- RGBForeColor (oldFore);
- RGBBackColor (oldBack);
-
- SetGWorld(oldGW,oldGD);
- UpdateProgress (params,3,3);
-
- { restore offscreen pixmaps' state }
- HSetState (Handle(srcA),stateA);
- SetPixelsState(srcA,pmStateA);
- HSetState (Handle(srcB),stateB);
- SetPixelsState(srcB,pmStateB);
- HSetState (Handle(dest),stateDest);
- SetPixelsState(dest,pmStateDest);
-
- DoProcessFrame := noErr;
- END;
-
- END.
-